package com.lmoumou.lib_pdfload.code

import java.io.IOException
import java.io.OutputStream

/**
 * @author Lmoumou
 * @date : 2019/8/27 15:46
 */
class BASE64Encoder :CharacterEncoder() {
    protected override fun bytesPerAtom(): Int {
        return 3
    }

    protected override fun bytesPerLine(): Int {
        return 57
    }

    private val pem_array = charArrayOf(
        'A',
        'B',
        'C',
        'D',
        'E',
        'F',
        'G',
        'H',
        'I',
        'J',
        'K',
        'L',
        'M',
        'N',
        'O',
        'P',
        'Q',
        'R',
        'S',
        'T',
        'U',
        'V',
        'W',
        'X',
        'Y',
        'Z',
        'a',
        'b',
        'c',
        'd',
        'e',
        'f',
        'g',
        'h',
        'i',
        'j',
        'k',
        'l',
        'm',
        'n',
        'o',
        'p',
        'q',
        'r',
        's',
        't',
        'u',
        'v',
        'w',
        'x',
        'y',
        'z',
        '0',
        '1',
        '2',
        '3',
        '4',
        '5',
        '6',
        '7',
        '8',
        '9',
        '+',
        '/',
        '='
    )

    @Throws(IOException::class)
    protected override fun encodeAtom(
        paramOutputStream: OutputStream,
        paramArrayOfByte: ByteArray, paramInt1: Int, paramInt2: Int
    ) {
        val i: Int
        val j: Int
        val k: Int
        if (paramInt2 == 1) {
            i = paramArrayOfByte[paramInt1].toInt()
            j = 0
            k = 0
            paramOutputStream.write(pem_array[i.ushr(2) and 0x3F].toInt())
            paramOutputStream
                .write(pem_array[(i shl 4 and 0x30) + (j.ushr(4) and 0xF)].toInt())
            paramOutputStream.write(61)
            paramOutputStream.write(61)
        } else if (paramInt2 == 2) {
            i = paramArrayOfByte[paramInt1].toInt()
            j = paramArrayOfByte[paramInt1 + 1].toInt()
            k = 0
            paramOutputStream.write(pem_array[i.ushr(2) and 0x3F].toInt())
            paramOutputStream
                .write(pem_array[(i shl 4 and 0x30) + (j.ushr(4) and 0xF)].toInt())
            paramOutputStream
                .write(pem_array[(j shl 2 and 0x3C) + (k.ushr(6) and 0x3)].toInt())
            paramOutputStream.write(61)
        } else {
            i = paramArrayOfByte[paramInt1].toInt()
            j = paramArrayOfByte[paramInt1 + 1].toInt()
            k = paramArrayOfByte[paramInt1 + 2].toInt()
            paramOutputStream.write(pem_array[i.ushr(2) and 0x3F].toInt())
            paramOutputStream
                .write(pem_array[(i shl 4 and 0x30) + (j.ushr(4) and 0xF)].toInt())
            paramOutputStream
                .write(pem_array[(j shl 2 and 0x3C) + (k.ushr(6) and 0x3)].toInt())
            paramOutputStream.write(pem_array[k and 0x3F].toInt())
        }
    }
}